|
- import createVerovioModule from 'verovio/wasm';
- import { VerovioToolkit } from 'verovio/esm';
- import { readFile, readdir } from 'node:fs/promises';
- import { JSDOM } from 'jsdom';
- import type {APIRoute, GetStaticPaths} from 'astro';
- // @ts-ignore
- import tailwindConfig from '../../../tailwind.config.mjs';
-
- const filter = (musicXml: string) => {
- const jsdom = new JSDOM(musicXml, { pretendToBeVisual: true, contentType: 'image/svg+xml' });
- const win = jsdom.window;
- // const win = jsdom.window;
- return win.document.documentElement.outerHTML;
- };
-
- const processOutput = (xmlData: string) => {
- const jsdom = new JSDOM(xmlData, { pretendToBeVisual: true, contentType: 'image/svg+xml' });
- const win = jsdom.window;
-
- const [svgElemsRoot, svgElemsMain] = Array.from(win.document.getElementsByTagName('svg'));
- if (typeof svgElemsRoot === 'undefined') {
- return '';
- }
-
- if (typeof svgElemsMain === 'undefined') {
- return '';
- }
-
- // svgElemsRoot.getAttributeNames().forEach((a) => {
- // const attr = svgElemsRoot.getAttribute(a);
- // if (!attr) {
- // return;
- // }
- // svgElemsMain.setAttribute(a, attr);
- // });
-
- Array.from(svgElemsRoot.children).forEach((h) => {
- if (h !== svgElemsMain) {
- h.remove();
- if (h.tagName.toLowerCase() === 'desc') {
- return;
- }
- if (h.tagName.toLowerCase() === 'style') {
- h.innerHTML = h.innerHTML.replace(/Times,serif/g, tailwindConfig.theme.fontFamily.body.join(','));
- }
- if (svgElemsMain.children[0]) {
- svgElemsMain.insertBefore(h, svgElemsMain.children[0]);
- return;
- }
- svgElemsMain.appendChild(h);
- }
- });
-
- Array.from(win.document.getElementsByClassName('pgHead')).forEach(h => {
- h.remove();
- });
-
- Array.from(win.document.getElementsByClassName('pgFoot')).forEach(h => {
- h.remove();
- });
-
- Array.from(win.document.getElementsByTagName('defs')).forEach(h => {
- h.remove();
- if (svgElemsMain) {
- if (svgElemsMain.children[0]) {
- svgElemsMain.insertBefore(h, svgElemsMain.children[0]);
- } else {
- svgElemsMain.appendChild(h);
- }
- }
- });
-
- return `<?xml version="1.0" encoding="utf-8"?>${svgElemsMain.outerHTML}`
- };
-
- export const GET: APIRoute = async ({ params }) => {
- const verovioModule = await createVerovioModule();
- const score = await readFile(`public/scores/${params.asset}.musicxml`, 'utf-8');
- const verovioToolkit = new VerovioToolkit(verovioModule);
- const filteredScore = filter(score);
- const isSuccessful = verovioToolkit.loadData(filteredScore);
- if (!isSuccessful) {
- return new Response(null, { status: 500 });
- }
-
- verovioToolkit.setOptions({
- breaks: 'none',
- font: 'Bravura',
- bottomMarginHeader: 0,
- bottomMarginArtic: 0,
- bottomMarginHarm: 0,
- topMarginHarm: 0,
- topMarginArtic: 0,
- topMarginPgFooter: 0,
- pageMarginTop: 0,
- pageMarginBottom: 0,
- pageMarginRight: 0,
- pageMarginLeft: 0,
- defaultBottomMargin: 0,
- defaultTopMargin: 0,
- defaultLeftMargin: 0,
- defaultRightMargin: 0,
- });
-
- let data: string;
- try {
- const raw = verovioToolkit.renderToSVG(1)
- .replace(/xmlns:mei="(.+?)"/g, '')
- .replace(/xlink:/g, '');
- data = processOutput(raw);
- } catch (err) {
- console.error(err);
- return new Response(null, { status: 500 });
- }
-
- return new Response(
- data,
- {
- headers: {
- 'Content-Type': 'image/svg+xml',
- },
- status: 200,
- }
- );
- };
-
- export const getStaticPaths: GetStaticPaths = async () => {
- const files = await readdir('public/scores');
- return files
- .filter((f) => f.endsWith('.musicxml'))
- .map((f) => ({
- params: {
- asset: f.replace(/\.musicxml/g, ''),
- },
- }));
- };
|